/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package servergui;

import Shared.NodeInfo;
import DAO_BUS.MyTable;
import DataObject.TableObject;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.util.Vector;
import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;

/**
 *
 * @author Backkom
 */
public class MainScreen extends JDialog implements ActionListener, MouseListener {

    ServerScreen server;
    protected JPanel treePanel;
    protected DefaultTreeModel treeModel;
    protected DefaultMutableTreeNode root;
    protected JTree tree;
    protected JTabbedPane tabsPanel;
    protected MenuBarCustom menuManager;
    boolean enterTree = false;
    int ScreenWidth;
    int ScreenHeight;
    File src;
    File des;
    JDialog dia;
    int[] SelectIndex = null;

    public MainScreen(String title, ServerScreen sv) throws HeadlessException {
        super(sv, title, false);
        JDialog.setDefaultLookAndFeelDecorated(true);
        Toolkit tool = Toolkit.getDefaultToolkit();
        ScreenWidth = tool.getScreenSize().width;
        ScreenHeight = tool.getScreenSize().height;
        server = sv;
        menuManager = new MenuBarCustom(this);
        this.setJMenuBar(menuManager.menuBar);
        this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        this.setLayout(null);
        this.setLocation(100, 0);
        this.setPreferredSize(new Dimension(ScreenWidth - 500, 700));
        menuManager.menuBar.setPreferredSize(new Dimension(this.getWidth(), 30));
        this.addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent e) {
                MainScreen.this.dispose();
                MainScreen.this.server.file.setEnabled(true);
                MainScreen.this.server.Start();
                super.windowClosing(e);
            }
        });
        tabsPanel = new JTabbedPane();
        InitTrees();
    }

    public void setPanel(JPanel panel, String tabName) {
        BorderLayout layout = new BorderLayout();
        JPanel Borderpanel;
        Borderpanel = new JPanel(layout);
        if (panel == null || tabName == null) {
            Borderpanel.add(treePanel, BorderLayout.WEST);
        } else {
            tabsPanel.add(panel);
            int index = tabsPanel.indexOfComponent(panel);
            tabsPanel.setTitleAt(index, tabName);
            tabsPanel.setTabComponentAt(index, CreateTabComponents(tabName));
            tabsPanel.setSelectedIndex(index);
            Borderpanel.add(treePanel, BorderLayout.WEST);
            Borderpanel.add(tabsPanel, BorderLayout.CENTER);
        }
        this.getContentPane().removeAll();
        this.setContentPane(Borderpanel);
        this.paintAll(this.getGraphics());
    }

    public void Show() {
        pack();
        setVisible(true);
    }

    private void InitTrees() {
        treePanel = new JPanel(new BorderLayout(), true);
        root = new DefaultMutableTreeNode(new NodeInfo("CSDL", "root"));
        treeModel = new DefaultTreeModel(root);
        tree = new JTree(treeModel);
        CreateTree();
        tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
        tree.setShowsRootHandles(false);
        tree.setRowHeight(20);
        tree.setExpandsSelectedPaths(true);
        tree.setName("tree");
        tree.setCellRenderer(new TreeRenderer());

        JScrollPane scrollTree = new JScrollPane(tree);
        treePanel.add(scrollTree, BorderLayout.CENTER);
        treePanel.setPreferredSize(new Dimension(200, this.getHeight()));
        tree.addMouseListener(this);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
    }

    public void showPopup(MouseEvent e) {
        if (e.isPopupTrigger() && tree.getSelectionCount() == 0) {
            menuManager.ShowPopup(e, 0, e.getPoint());
        }
    }

    public boolean checkTreeSelect(MouseEvent e) {
        int row = tree.getRowForLocation(e.getX(), e.getY());
        if (row == -1) {
            tree.clearSelection();
            menuManager.TreeSelect(0);
            return false;
        }
        if (e.isPopupTrigger()) {
            tree.setSelectionRow(row);
            DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
            String nodeType = ((NodeInfo) node.getUserObject()).GetType();
            String name = ((NodeInfo) node.getUserObject()).toString();
            if (nodeType.compareToIgnoreCase("root") == 0) {
                menuManager.ShowPopup(e, 0, e.getPoint());
            }
            if (nodeType.compareToIgnoreCase("db") == 0) {
                if (name.equals("AccountManager")) {
                    return false;
                }
                menuManager.ShowPopup(e, 1, e.getPoint());
                menuManager.TreeSelect(1);
                return true;
            }
            if (nodeType.compareToIgnoreCase("tb") == 0) {
                menuManager.ShowPopup(e, 2, e.getPoint());
                menuManager.TreeSelect(2);
                return true;
            }
            menuManager.TreeSelect(0);
        }
        return true;
    }

    private JComponent CreateTabComponents(String title) {
        JLabel label = new JLabel(title);
        label.setFont(new Font("Arial", Font.ITALIC, 10));
        JLabel close = new JLabel(new ImageIcon("src/close_icon.png"));
        close.setForeground(Color.red);
        close.setPreferredSize(new Dimension(20, 20));
        close.setFont(new Font("Arial", Font.BOLD, 10));
        close.setAlignmentX(RIGHT_ALIGNMENT);
        close.setToolTipText("Close this tab");
        close.setName(title);
        close.addMouseListener(this);
        JPanel pane = new JPanel(true);
        pane.add(label);
        pane.add(close);
        pane.setOpaque(false);
        return pane;
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        String name = e.getComponent().getName();
        int Action = tabsPanel.indexOfTab(name);
        if (name.endsWith("**")) {
            Action = tabsPanel.indexOfTab(name.replace("**", " Design"));
        }
        if (Action >= 0 && Action < tabsPanel.getTabCount()) {
            closeTab(Action);
        }

        if (name.compareToIgnoreCase("tree") == 0) {
            int row = tree.getRowForLocation(e.getX(), e.getY());
            if (row == -1) {
                tree.clearSelection();
                menuManager.TreeSelect(0);
            } else {
                DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
                String nodeType = ((NodeInfo) node.getUserObject()).GetType();
                if (nodeType.compareToIgnoreCase("root") == 0) {
                    menuManager.TreeSelect(0);
                }
                if (nodeType.compareToIgnoreCase("db") == 0) {
                    menuManager.TreeSelect(1);
                }
                if (nodeType.compareToIgnoreCase("tb") == 0) {
                    menuManager.TreeSelect(2);
                }
            }
        }
    }

    @Override
    public void mousePressed(MouseEvent e) {
        String name = e.getComponent().getName();
        if (name.compareToIgnoreCase("tree") == 0) {
            if (!checkTreeSelect(e)) {
                showPopup(e);
            }
        }
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        String name = e.getComponent().getName();
        if (name.compareToIgnoreCase("tree") == 0) {
            if (!checkTreeSelect(e)) {
                showPopup(e);
            }
        }
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        String name = e.getComponent().getName();
        if (name.compareToIgnoreCase("tree") == 0) {
            enterTree = true;
        }
    }

    @Override
    public void mouseExited(MouseEvent e) {
        String name = e.getComponent().getName();
        if (name.compareToIgnoreCase("tree") == 0) {
            enterTree = false;
        }
    }

    private void CreateTree() {
        File[] file = new File[server.database.size()];
        server.database.toArray(file);
        for (int i = 0; i < file.length; i++) {
            String dbName = file[i].getName().replace(".en", "").trim();
            DefaultMutableTreeNode db = new DefaultMutableTreeNode(new NodeInfo(dbName, "db"), true);
            treeModel.insertNodeInto(db, root, 0);
            tree.scrollPathToVisible(new TreePath(db.getPath()));
            for (MyTable j : (Vector<MyTable>) server.tables.elementAt(i)) {
                DefaultMutableTreeNode tb = new DefaultMutableTreeNode(new NodeInfo(j.GetName(), "tb"), false);
                treeModel.insertNodeInto(tb, db, 0);
            }
        }
    }

    void viewDesign() {
        //Get node selected
        DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
        DefaultMutableTreeNode parent = (DefaultMutableTreeNode) node.getParent();
        String tbName = ((NodeInfo) node.getUserObject()).toString();
        String dbName = ((NodeInfo) parent.getUserObject()).toString();
        //Get table with name
        MyTable tb = server.getTable(dbName, tbName);
        //Get data to view        
        Vector<TableObject> lst = new Vector<>();
        //Create Design View
        lst = tb.getDesignInfo();
        boolean isNew = false;
        if(tb.isEmpty())
        {
            isNew=true;
        }
        DesignView tbView = new DesignView(this, dbName, tbName, lst, isNew);
        setPanel(tbView, tbName + " Design");
        Show();
    }

    void viewData() {
        //Get node selected
        DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
        DefaultMutableTreeNode parent = (DefaultMutableTreeNode) node.getParent();
        String tbName = ((NodeInfo) node.getUserObject()).toString();
        String dbName = ((NodeInfo) parent.getUserObject()).toString();
        //Get table with name
        MyTable tb = server.getTable(dbName, tbName);
        //Get data to view
        Vector<TableObject> lst = new Vector<>();
        Vector<Class> cls = new Vector<>();
        String[] header = tb.getTableObjectData(lst, cls);
        if (header != null) {
            //Create TableView
            TableViewData tbView = new TableViewData(server, dbName, tbName, header, cls, lst);
            setPanel(tbView, tbName + "View");
            Show();
        } else {
            JOptionPane.showMessageDialog(this, "Loadding fail!", "Error", JOptionPane.ERROR_MESSAGE);
        }
    }

    void queryDB() {
        DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
        String dbName = ((NodeInfo) node.getUserObject()).toString();

        int qvTab = tabsPanel.indexOfTab("Query All");
        if (qvTab >= 0 && qvTab < tabsPanel.getTabCount()) {
            tabsPanel.setSelectedIndex(qvTab);
        } else {
            QueryView qv = new QueryView(server, dbName);
            setPanel(qv, "Query All");
            Show();
        }

    }

    void ShowAbout() {
        String pr = "Group develop software: \"Database query application(DQA)\".\n\t Class: LTUDJAVA-2009/3.";
        JOptionPane.showMessageDialog(this, pr, "About", JOptionPane.PLAIN_MESSAGE);
    }

    void Update(String tableName, boolean saved) {
        int Action = -1;
        Action = tabsPanel.indexOfTab(tableName + " Design");
        if (Action >= 0 && Action < tabsPanel.getTabCount()) {
            if (!saved) {
                tabsPanel.setTabComponentAt(Action, CreateTabComponents(tableName + "**"));
            } else {
                tabsPanel.setTabComponentAt(Action, CreateTabComponents(tableName + " Design"));
            }
        }
    }

    boolean CheckDuplicateTableorDatabaseName(String dbName, String tbName, boolean isTable) {
        if (isTable) {
            //Table Check
            for (int i = 0; i < server.database.size(); i++) {
                if (server.database.get(i).getName().equalsIgnoreCase(dbName + ".en")) {
                    for (MyTable tb : (Vector<MyTable>) server.tables.elementAt(i)) {
                        if (tb.GetName().equalsIgnoreCase(tbName)) {
                            return true;
                        }
                    }
                }
            }
        } else {
            //Database Check
            for (File f : server.database) {
                if (f.getName().equalsIgnoreCase(dbName + ".en")) {
                    return true;
                }
            }
        }
        return false;
    }

    void SaveDesign(String databaseName, String tableName, Vector<TableObject> listObject, boolean isNew) {
        for (int i = 0; i < listObject.size();) {
            if (listObject.elementAt(i).hasNull()) {
                listObject.remove(i);
            } else {
                i++;
            }
        }
        server.SaveDesign(databaseName, tableName, listObject, isNew);
    }

    void closeTab(int i) {
        int Action = i;
        if (i < 0) {
            Action = tabsPanel.getSelectedIndex();
        }
        Component c = tabsPanel.getComponentAt(Action);
        Boolean sc = true;
        if (c instanceof DesignView) {
            sc = ((DesignView) c).Exits();
        }
        if (sc) {
            tabsPanel.remove(Action);
        }
    }

    public void addNode(String name) {
        DefaultMutableTreeNode parentNode = null;
        TreePath parentPath = tree.getSelectionPath();

        if (parentPath != null) {
            parentNode = (DefaultMutableTreeNode) (parentPath.getLastPathComponent());
        } else {
            parentNode = root;
        }
        String parentType = ((NodeInfo) parentNode.getUserObject()).GetType();
        DefaultMutableTreeNode childNode = null;
        if (parentType.compareTo("root") == 0) {
            if (CheckDuplicateTableorDatabaseName(name, "", false)) {
                JOptionPane.showMessageDialog(this, "Database is exists", "Error", JOptionPane.ERROR_MESSAGE);
            } else {
                if (!server.AddTBorDB(name, "", false)) {
                    JOptionPane.showMessageDialog(this, "Cannot add this database", "Error", JOptionPane.ERROR_MESSAGE);
                } else {
                    childNode = new DefaultMutableTreeNode(new NodeInfo(name, "db"), true);
                }
            }
        }
        if (parentType.compareTo("db") == 0) {
            if (CheckDuplicateTableorDatabaseName(parentNode.toString(), name, true)) {
                JOptionPane.showMessageDialog(this, "Table is exists", "Error", JOptionPane.ERROR_MESSAGE);
            } else {
                if (!server.AddTBorDB(parentNode.toString(), name, true)) {
                    JOptionPane.showMessageDialog(this, "Cannot add this table", "Error", JOptionPane.ERROR_MESSAGE);
                } else {
                    childNode = new DefaultMutableTreeNode(new NodeInfo(name, "tb"), false);
                }
            }
        }
        if (childNode != null) {
            treeModel.insertNodeInto(childNode, parentNode,
                    parentNode.getChildCount());
            tree.scrollPathToVisible(new TreePath(childNode.getPath()));
        }
    }

    void Close() {
        this.dispose();
        server.file.setEnabled(true);
        server.Start();
        // System.exit(0);
    }

    void deleteNode() {
        DefaultMutableTreeNode parentNode = null;
        DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
        TreePath parentPath = tree.getSelectionPath();
        if (parentPath != null) {
            parentNode = (DefaultMutableTreeNode) (parentPath.getLastPathComponent());
        } else {
            parentNode = root;
        }
        String parentType = ((NodeInfo) parentNode.getUserObject()).GetType();
        String dbName = "", tbName = "";
        boolean delete = false, isTable = true;
        if (parentType.compareTo("tb") == 0) {
            dbName = parentNode.getParent().toString();
            tbName = parentNode.toString();
            if (dbName.equals("AccountManager")) {
                JOptionPane.showMessageDialog(this, "Cannot delete Accounts Table", "Error", JOptionPane.ERROR_MESSAGE);
                delete = false;
            } else {
                if (!server.DeleteTBorDB(dbName, tbName, true)) {
                    JOptionPane.showMessageDialog(this, "Cannot delete this table", "Error", JOptionPane.ERROR_MESSAGE);
                } else {
                    delete = true;
                }
            }
        }
        if (parentType.compareTo("db") == 0) {
            dbName = parentNode.toString();
            if (!server.DeleteTBorDB(dbName, tbName, false)) {
                JOptionPane.showMessageDialog(this, "Cannot delete this database", "Error", JOptionPane.ERROR_MESSAGE);
            } else {
                delete = true;
                isTable = false;
            }
        }
        if (delete) {
            for (Component c : tabsPanel.getComponents()) {
                boolean del = false;
                if (c instanceof QueryView) {
                    QueryView qv = (QueryView) c;
                    if (!isTable && qv.databaseName.equalsIgnoreCase(dbName)) {
                        del = true;
                    }
                }
                if (c instanceof DesignView) {
                    DesignView dv = (DesignView) c;
                    if (dv.databaseName.equalsIgnoreCase(dbName)) {
                        del = true;
                        if (isTable && !dv.tableName.equalsIgnoreCase(tbName)) {
                            del = false;
                        }
                    }
                }
                if (c instanceof TableViewData) {
                    TableViewData tv = (TableViewData) c;
                    if (tv.databaseName.equalsIgnoreCase(dbName)) {
                        del = true;
                        if (isTable && !tv.tableName.equalsIgnoreCase(tbName)) {
                            del = false;
                        }
                    }
                }
                if (del) {
                    tabsPanel.remove(c);
                }
            }
            model.removeNodeFromParent(parentNode);
            treePanel.paintAll(treePanel.getGraphics());
        }
    }
}
